
import Style from 'ol/style/style';
import StyleIcon from 'ol/style/icon';
import StyleStroke from 'ol/style/stroke';
import StyleFill from 'ol/style/fill';
import * as Color from 'color';

export interface StylePointOptions {
    "marker-color": string,
    "marker-size": MarkerSize;
    "marker-symbol": string;
}

export interface StyleLineOptions {
    "stroke": string,
    "stroke-width": number,
    "stroke-opacity": number
}

export interface StylePolygonOptions {
    "stroke": string,
    "stroke-width": number,
    "stroke-opacity": number,
    "fill": string,
    "fill-opacity": number
}

export interface StyleOptions {
    "point": StylePointOptions,
    "line": StyleLineOptions,
    "polygon": StylePolygonOptions
}

export enum MarkerSize {
    small = 's',
    medium = 'm',
    large = 'l'
}

export class SimStyle {

    private point: SimStylePoint;
    private line: SimStyleLine;
    private polygon: SimStylePolygon;

    constructor(options: StyleOptions) {
        if(options.point) {
            this.point = new SimStylePoint(options.point);
        }
        if(options.line) {
            this.line = new SimStyleLine(options.line);
        }
        if(options.polygon) {
            this.polygon = new SimStylePolygon(options.polygon);
        }
    }

    getStyleAsOl(): any {
        const fill = this.polygon ? this.polygon.getStyleAsOl() : [];
        const image = this.point ? this.point.getStyleAsOl() : [];
        const stroke = this.line ? this.line.getStyleAsOl() : [];
        return [ ...fill, ...image, ...stroke ];
    }

    getPoint(): SimStylePoint {
        return this.point;
    }

    getPointAsOl(): any {
        if(this.point) {
            return this.point.getStyleAsOl();
        } else {
            return null;
        }
    }

    getLine(): SimStyleLine {
        return this.line;
    }

    getLineAsOl(): any  {
        if(this.line) {
            return this.line.getStyleAsOl();
        } else {
            return null;
        }
    }

    getPolygon(): SimStylePolygon {
        return this.polygon;
    }

    getPolygonAsOl(): any {
        if(this.polygon) {
            return this.polygon.getStyleAsOl();
        } else {
            return null;
        }
    }

}

export class SimStylePoint {

    private style: any[];

    constructor(options: StylePointOptions) {
        const mapboxToken: string = 'pk.eyJ1Ijoiam9ubnl0b3NoZW4iLCJhIjoiY2ozeHJreHllMDA0cjJ3bXhkYjlnaDl5eCJ9.VYbgk1Z2yUiDV5Z9_TGwTg';
        const symbol = options["marker-symbol"] ? `-${options["marker-symbol"]}` : ``;
        const size = options["marker-size"] || 'm';
        const color = (new Color(options["marker-color"])).hex().replace('#', '');
        const imgUrl: string = `https://a.tiles.mapbox.com/v4/marker/pin-${size}${symbol}+${color}.png?access_token=${mapboxToken}`;
        this.style = [
            new Style({
                image: new StyleIcon({
                    src: imgUrl
                })
            })
        ];
    }

    getStyleAsOl(): any {
        return this.style;
    }

}

export class SimStyleLine {

    private style: any[];

    constructor(options: StyleLineOptions) {
        this.style = [
            // new Style({
            //     stroke: new StyleStroke({
            //         color: [255, 255, 255, 0.5],
            //         width: options["stroke-width"] + 2
            //     })
            // }),
            new Style({
                stroke: new StyleStroke({
                    color: (new Color(options["stroke"])).alpha(options["stroke-opacity"]).array(),
                    width: options["stroke-width"]
                })
            })
        ]
    }

    getStyleAsOl(): any {
        return this.style;
    }
}

export class SimStylePolygon {
    
    private style: any[];

    constructor(options: StylePolygonOptions) {
        this.style = [
            new Style({
                stroke: new StyleStroke({
                    color: (new Color(options.stroke)).alpha(options["stroke-opacity"]).array(),
                    width: options["stroke-width"]
                }),
                fill: new StyleFill({
                    color: (new Color(options.fill)).alpha(options["fill-opacity"]).array()
                })
            })
        ];
    }

    getStyleAsOl(): any {
        return this.style;
    }
}